#pragma once
#include "Singleton.hpp"
#include <boost/asio.hpp>
#include <boost/asio/io_context.hpp>
#include <cstddef>
#include <memory>
#include <thread>
#include <vector>

class AsioIoContextPool : public Singleton<AsioIoContextPool> {
  friend class Singleton<AsioIoContextPool>;

public:
  using IoContext = boost::asio::io_context;
  using Work = boost::asio::io_context::work;
  using WorkPtr = std::unique_ptr<Work>;
  ~AsioIoContextPool();
  boost::asio::io_context &GetIoContext();
  void Stop();

private:
  AsioIoContextPool(std::size_t size = std::thread::hardware_concurrency());
  std::vector<IoContext> _ioContext;
  std::vector<WorkPtr> _works;
  std::vector<std::thread> _threads;
  std::size_t _nextIoContext;
};